package com.xinlu.common.exception.handle;

import java.util.Arrays;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.util.TextProviderHelper;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;
import com.xinlu.common.exception.CommonException;
import com.xinlu.common.exception.DBException;
import com.xinlu.common.exception.LogicException;
import com.xinlu.common.exception.SysException;
import com.xinlu.common.log.Logger;
import com.xinlu.derek.common.BaseAction;
import com.xinlu.derek.common.BaseForm;

public class CommonExceptionHandle implements ExceptionHandle{

	protected static Logger logger = Logger.getLogger(CommonExceptionHandle.class);

	private BaseAction action;

	public CommonExceptionHandle(BaseAction action) {

		this.action = action;
	}
	
	public String handleException(Exception e) throws CommonException {
		
		// ///////////////////////////////////////////
		// // Restore user input
		// ///////////////////////////////////////////
		restoreInput();

		// ///////////////////////////////////////////
		// // analyze exception
		// ///////////////////////////////////////////
		analyzeException(e);

		return Action.INPUT;
//		return "errorPage";
		
	}
	
	/**
	 * 
	 * Function: Restore user input
	 * 
	 * Produce describe:
	 * 
	 */
	private void restoreInput() {
		
		try {
			// /////////////////////////
			// // Get Form
			// ////////////////////////
		
			BaseForm form = (BaseForm) action.getModel();

			//	Form2String.restoreForm(form);
		} catch (SysException e1) {
			e1.printStackTrace();
		}
	}

	/**
	 * 
	 * Function: 分析异常，进行统一处理
	 * 
	 * Produce describe:
	 * 
	 * @param e
	 * @throws SysException
	 * @throws DBException
	 * @throws LogicException
	 */
	protected void analyzeException(Exception e) throws CommonException {

		// 判断是否为父类异常，是则进行资源文件信息处理，否则直接抛出系统异常
		if (!(e instanceof CommonException)) {

			e = new SysException("exception.sys.E00001", e);
		}

		CommonException ex = (CommonException) e;

		String msg = getExceptionMsg(ex);

		// 保存错误到ValueStack中
		if (msg != null) {
			ActionContext.getContext().getValueStack().setValue("actionErrors", msg);
		}

		ex.setErrCode(msg);

		// 输出异常日志
		logger.log(ex.getExceptionLevel(), ex.getErrCode(), ex, true);
		
		//	ServletActionContext.getRequest().setAttribute("exception", ex);

		// 判断该异常是否要进行抛出
		if (!ex.getCurrentPageShow()) {

			throw ex;
		}
	}

	/**
	 * 
	 * Function: 根据逻辑异常获取异常的错误消息
	 * 
	 * Produce describe:
	 * 
	 * @param logic
	 * @return
	 */
	protected String getExceptionMsg(CommonException ex) {

		String msg = "";

		//如果errCode为空，则默认为未知错误提示信息
		if(StringUtils.isEmpty(ex.getErrCode())){
			ex.setErrCode("exception.sys.E00002");
		}
		
		ValueStack valueStack = ActionContext.getContext().getValueStack();

		// 得到异常的参数代码
		Object[] param = null;

		// 多个参数
		if ((ex.getArgs() != null && ex.getArgs().length > 0)) {

			param = ex.getArgs();

		} else if (StringUtils.isNotEmpty(ex.getArg())) {

			// 一个参数
			param = new String[] { ex.getArg() };
		}

		// 获取异常的消息
		if (param != null && param.length > 0) {

			// 解析异常的参数代码
			for (int i = 0; i < param.length; i++) {

				String tmp = TextProviderHelper.getText(param[i].toString(), param[i].toString(), valueStack);

				if (StringUtils.isNotEmpty(tmp)) {
					param[i] = tmp;
				}

			}

			msg = TextProviderHelper.getText(ex.getErrCode(), ex.getErrCode(), Arrays.asList(param), valueStack);

		} else {

			msg = TextProviderHelper.getText(ex.getErrCode(), ex.getErrCode(), valueStack);
		}

		return msg;
	}

}
